package org.wlldTest.translate;


import org.dromara.easyai.config.SentenceConfig;
import org.dromara.easyai.config.TfConfig;
import org.dromara.easyai.entity.SentenceModel;
import org.dromara.easyai.entity.WordTwoVectorModel;
import org.dromara.easyai.matrixTools.Matrix;
import org.dromara.easyai.matrixTools.MatrixList;
import org.dromara.easyai.matrixTools.MatrixOperation;
import org.dromara.easyai.naturalLanguage.word.WordEmbedding;
import org.dromara.easyai.transFormer.TransFormerManager;
import org.dromara.easyai.transFormer.nerve.SensoryNerve;
import org.wlldTest.myUnet.WordAndId;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lidapeng
 * @time 2025/2/24 14:17
 */
public class Test {
    public static TfConfig config = new TfConfig();//最外层配置文件
    public static WordEmbedding wordEmbedding = new WordEmbedding();//词向量嵌入器
    public static int wordVectorDimension = 16;//设置词向量维度
    public static TransFormerManager transFormerManager;
    public static MatrixOperation matrixOperation = new MatrixOperation();

    public static void main(String[] args) throws Exception {
        init();//初始化操作
        study();
    }


    public static void init() throws Exception {
        wordEmbedding.setConfig(new SentenceConfig());//词向量设置配置类
        wordEmbedding.setStudyTimes(100);//词向量训练循环100次
        SentenceModel sentenceModel = new SentenceModel(" ");//设置隔断符训练样本类
        List<String[]> talkBodies = data();//读取测试数据
        for (String[] sens : talkBodies) {//塞入测试数据
            for (String sen : sens) {
                sentenceModel.setSentenceBySplitWord(sen);//将回答塞入有隔断符号样本类
            }
        }
        wordEmbedding.init(sentenceModel, wordVectorDimension);//初始化词向量嵌入
        wordEmbedding.start();//词向量训练完毕，并返回词向量模型
        config.setTypeNumber(wordEmbedding.getWordList().size());
        config.setMaxLength(5);//最大长度设置为40
        config.setMultiNumber(3);//每层编解码器设置3个多头
        config.setFeatureDimension(wordVectorDimension);//设置词向量维度
        config.setAllDepth(1);//设置tf编解码器深度
        config.setSplitWord(" ");//设置空格为词隔断符
        config.setSelfTimeCode(false);//设置为对称三角函数位置编码
        config.setTimes(500);//循环训练五百次
        config.setStudyPoint(0.005f);//设置tf学习率
        config.setShowLog(true);//对学习中的数据打印
        transFormerManager = new TransFormerManager(config);
    }

    public static void study() throws Exception {
        List<String[]> talkBodies = data();//读取测试数据
        SensoryNerve sensoryNerve = transFormerManager.getSensoryNerve();
        for (int i = 0; i < 10; i++) {
            for (String[] sens : talkBodies) {
                for (String sen : sens) {//每个词汇
                    WordAndId wordAndId = getFeatureMatrix(sen.split(" "));
                    Matrix myFeature = wordAndId.getFeature();
                    Matrix start = transFormerManager.getStartMatrix(myFeature);//开始符
                    for (String sen2 : sens) {
                        MatrixList matrixList = new MatrixList(start, true, 20);//开始符
                        WordAndId wordAndId2 = getFeatureMatrix(sen2.split(" "));
                        Matrix myFeature2 = wordAndId2.getFeature();
                        List<Integer> ids = wordAndId2.getIds();
                        matrixList.add(myFeature2);
                        Matrix decodeMatrix = matrixList.getMatrix();//解码器特征
                        sensoryNerve.postMessage(1, myFeature, decodeMatrix, true, ids, null, false);
                    }
                }
            }
        }
        for (String[] sens : talkBodies) {
            for (String sen : sens) {
                MyWordBack myWordBack = new MyWordBack();
                System.out.println("语句==============" + sen);
                WordAndId wordAndId = getFeatureMatrix(sen.split(" "));
                Matrix myFeature = wordAndId.getFeature();
                Matrix start = transFormerManager.getStartMatrix(myFeature);//开始符
                sensoryNerve.postMessage(3, myFeature, start, false, null, myWordBack, false);
                Matrix feature = myWordBack.getMatrix();
                System.out.println(feature.getString());
            }
        }
//        TransFormerModel transFormerModel = transFormerManager.getModel();
//        writeModel(JSON.toJSONString(transFormerModel), "/Users/lidapeng/job/linshi/w1.json");
//        writeModel(JSON.toJSONString(wordTwoVectorModel), "/Users/lidapeng/job/linshi/l1.json");

    }

    public static WordAndId getFeatureMatrix(String[] words) throws Exception {
        Matrix myFeature = null;
        WordAndId wordAndId = new WordAndId();
        List<Integer> ids = new ArrayList<>();
        wordAndId.setIds(ids);
        for (int i = 0; i < words.length; i++) {
            String word = words[i];
            ids.add(wordEmbedding.getID(word) + 2);
            Matrix feature = wordEmbedding.getEmbedding(word, 1, true).getFeatureMatrix();
            if (i == 0) {
                myFeature = feature;
            } else {
                myFeature = matrixOperation.pushVector(myFeature, feature, true);
            }
        }
        ids.add(1);
        wordAndId.setFeature(myFeature);
        return wordAndId;
    }

    public static List<String[]> data() {//配置测试用三条训练数据
        List<String[]> sen = new ArrayList<>();
        String[] t1 = new String[]{"people no", "people id", "user id", "user no", "ren id", "ren no"};
        String[] t2 = new String[]{"state no", "order id", "dingdan no", "dingdan id", "state id"};
        sen.add(t1);
        sen.add(t2);
        return sen;
    }

    public static void writeModel(String model, String url) throws IOException {//写出模型与 激活参数
        OutputStreamWriter out = new OutputStreamWriter(Files.newOutputStream(Paths.get(url)), StandardCharsets.UTF_8);
        out.write(model);
        out.close();
    }

    private static String readPaper(File file) {
        InputStream read = null;
        String context = null;
        try {
            read = Files.newInputStream(file.toPath());
            byte[] bt = new byte[read.available()];
            read.read(bt);
            context = new String(bt, StandardCharsets.UTF_8);
            read.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (read != null) {
                try {
                    read.close(); //确保关闭
                } catch (IOException el) {
                }
            }
        }
        return context;
    }
}
